using Microsoft.IdentityModel.Protocols.WSTrust;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security;
using System.Security.Permissions;
using System.Text;
namespace Net35.Xrm.Sdk.Client
{
	[SecuritySafeCritical]
	[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
	internal sealed class ServiceConfiguration<TService> : IEndpointSwitch
	{
		internal const string DefaultRequestType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue";
		private System.ServiceModel.Description.ServiceEndpoint currentServiceEndpoint;
		private TokenServiceCredentialType _tokenEndpointType = TokenServiceCredentialType.AsymmetricToken;
		private static object _lockObject = new object();
		public event EventHandler<EndpointSwitchEventArgs> EndpointSwitched;
		public event EventHandler<EndpointSwitchEventArgs> EndpointSwitchRequired;
		public bool EndpointAutoSwitchEnabled
		{
			get;
			set;
		}
		public string AlternateEndpointToken
		{
			get;
			set;
		}
		public System.Uri AlternateEndpoint
		{
			get;
			internal set;
		}
		public System.Uri PrimaryEndpoint
		{
			get;
			internal set;
		}
		public bool IsPrimaryEndpoint
		{
			get
			{
				bool result;
				lock (ServiceConfiguration<TService>._lockObject)
				{
					result = (this.CurrentServiceEndpoint.Address.Uri != this.AlternateEndpoint);
				}
				return result;
			}
		}
		public PolicyConfiguration PolicyConfiguration
		{
			get;
			set;
		}
		public ServiceEndpointMetadata ServiceEndpointMetadata
		{
			get;
			private set;
		}
		private bool ClaimsEnabledService
		{
			get
			{
				return this.AuthenticationType == AuthenticationProviderType.Federation || this.AuthenticationType == AuthenticationProviderType.OnlineFederation;
			}
		}
		public System.Uri ServiceUri
		{
			get;
			internal set;
		}
		public System.ServiceModel.Description.ServiceEndpoint CurrentServiceEndpoint
		{
			get
			{
				if (this.currentServiceEndpoint == null)
				{
					foreach (System.ServiceModel.Description.ServiceEndpoint current in this.ServiceEndpoints.Values)
					{
						if (this.ServiceUri.Port == current.Address.Uri.Port && this.ServiceUri.Scheme == current.Address.Uri.Scheme)
						{
							this.currentServiceEndpoint = current;
							break;
						}
					}
				}
				return this.currentServiceEndpoint;
			}
			set
			{
				this.currentServiceEndpoint = value;
			}
		}
		public IssuerEndpoint CurrentIssuer
		{
			get
			{
				if (this.CurrentServiceEndpoint != null)
				{
					return ServiceMetadataUtility.GetIssuer(this.CurrentServiceEndpoint.Binding);
				}
				return null;
			}
			set
			{
				if (this.CurrentServiceEndpoint != null)
				{
					this.CurrentServiceEndpoint.Binding = ServiceMetadataUtility.SetIssuer(this.CurrentServiceEndpoint.Binding, value);
				}
			}
		}
		public AuthenticationProviderType AuthenticationType
		{
			get
			{
				if (this.PolicyConfiguration is WindowsPolicyConfiguration)
				{
					return AuthenticationProviderType.ActiveDirectory;
				}
				if (this.PolicyConfiguration is ClaimsPolicyConfiguration)
				{
					return AuthenticationProviderType.Federation;
				}
				if (this.PolicyConfiguration is LiveIdPolicyConfiguration)
				{
					return AuthenticationProviderType.LiveId;
				}
				if (this.PolicyConfiguration is OnlineFederationPolicyConfiguration)
				{
					return AuthenticationProviderType.OnlineFederation;
				}
				return AuthenticationProviderType.None;
			}
		}
		public ServiceEndpointDictionary ServiceEndpoints
		{
			get;
			internal set;
		}
		public IssuerEndpointDictionary IssuerEndpoints
		{
			get;
			internal set;
		}
		public CrossRealmIssuerEndpointCollection CrossRealmIssuerEndpoints
		{
			get;
			internal set;
		}
		public string GetAlternateEndpointAddress(string host)
		{
			int startIndex = host.IndexOf('.');
			return host.Insert(startIndex, "." + this.AlternateEndpointToken);
		}
		public void OnEndpointSwitchRequiredEvent()
		{
			EventHandler<EndpointSwitchEventArgs> endpointSwitchRequired = this.EndpointSwitchRequired;
			this.HandleEndpointEvent(endpointSwitchRequired, (this.CurrentServiceEndpoint.Address.Uri == this.PrimaryEndpoint) ? this.AlternateEndpoint : this.PrimaryEndpoint, this.CurrentServiceEndpoint.Address.Uri);
		}
		public void OnEndpointSwitchedEvent()
		{
			EventHandler<EndpointSwitchEventArgs> endpointSwitched = this.EndpointSwitched;
			this.HandleEndpointEvent(endpointSwitched, this.CurrentServiceEndpoint.Address.Uri, (this.CurrentServiceEndpoint.Address.Uri == this.PrimaryEndpoint) ? this.AlternateEndpoint : this.PrimaryEndpoint);
		}
		private void HandleEndpointEvent(EventHandler<EndpointSwitchEventArgs> tmp, System.Uri newUrl, System.Uri previousUrl)
		{
			if (tmp != null)
			{
				EndpointSwitchEventArgs endpointSwitchEventArgs = new EndpointSwitchEventArgs();
				lock (ServiceConfiguration<TService>._lockObject)
				{
					endpointSwitchEventArgs.NewUrl = newUrl;
					endpointSwitchEventArgs.PreviousUrl = previousUrl;
				}
				tmp(this, endpointSwitchEventArgs);
			}
		}
		private void SetEndpointSwitchingBehavior()
		{
			if (this.ServiceEndpointMetadata.ServiceUrls == null)
			{
				return;
			}
			this.PrimaryEndpoint = this.ServiceEndpointMetadata.ServiceUrls.PrimaryEndpoint;
			bool flag = false;
			bool flag2 = true;
			if (!this.ServiceEndpointMetadata.ServiceUrls.GeneratedFromAlternate)
			{
				System.ServiceModel.Channels.BindingElementCollection bindingElementCollection = this.CurrentServiceEndpoint.Binding.CreateBindingElements();
				FailoverPolicy failoverPolicy = bindingElementCollection.Find<FailoverPolicy>();
				if (failoverPolicy != null && failoverPolicy.PolicyElements.ContainsKey("FailoverAvailable"))
				{
					flag = Convert.ToBoolean(failoverPolicy.PolicyElements["FailoverAvailable"], CultureInfo.InvariantCulture);
					flag2 = Convert.ToBoolean(failoverPolicy.PolicyElements["EndpointEnabled"], CultureInfo.InvariantCulture);
				}
			}
			else
			{
				flag = true;
			}
			if (flag)
			{
				this.AlternateEndpoint = this.ServiceEndpointMetadata.ServiceUrls.AlternateEndpoint;
				if (!flag2)
				{
					this.SwitchEndpoint();
				}
			}
		}
		public bool CanSwitch(System.Uri currentUri)
		{
			ClientExceptionHelper.ThrowIfNull(currentUri, "currentUri");
			bool result;
			lock (ServiceConfiguration<TService>._lockObject)
			{
				result = (currentUri == this.CurrentServiceEndpoint.Address.Uri);
			}
			return result;
		}
		public bool HandleEndpointSwitch()
		{
			if (this.AlternateEndpoint != null)
			{
				this.OnEndpointSwitchRequiredEvent();
				if (this.EndpointAutoSwitchEnabled)
				{
					this.SwitchEndpoint();
					return true;
				}
			}
			return false;
		}
		public void SwitchEndpoint()
		{
			if (this.AlternateEndpoint == null)
			{
				return;
			}
			lock (ServiceConfiguration<TService>._lockObject)
			{
				if (this.CurrentServiceEndpoint.Address.Uri != this.AlternateEndpoint)
				{
					this.CurrentServiceEndpoint.Address = new System.ServiceModel.EndpointAddress(this.AlternateEndpoint, this.CurrentServiceEndpoint.Address.Identity, this.CurrentServiceEndpoint.Address.Headers);
				}
				else
				{
					this.CurrentServiceEndpoint.Address = new System.ServiceModel.EndpointAddress(this.PrimaryEndpoint, this.CurrentServiceEndpoint.Address.Identity, this.CurrentServiceEndpoint.Address.Headers);
				}
				this.OnEndpointSwitchedEvent();
			}
		}
		internal static ServiceUrls CalculateEndpoints(System.Uri serviceUri)
		{
			ServiceUrls serviceUrls = new ServiceUrls();
			System.UriBuilder uriBuilder = new System.UriBuilder(serviceUri);
			string[] array = uriBuilder.Host.Split(new char[]
			{
				'.'
			});
			if (array[0].EndsWith("--s", StringComparison.OrdinalIgnoreCase))
			{
				serviceUrls.AlternateEndpoint = uriBuilder.Uri;
				array[0] = array[0].Remove(array[0].Length - 3);
				uriBuilder.Host = string.Join(".", array);
				serviceUrls.PrimaryEndpoint = uriBuilder.Uri;
				serviceUrls.GeneratedFromAlternate = true;
			}
			else
			{
				serviceUrls.PrimaryEndpoint = uriBuilder.Uri;
				string[] array2;
				(array2 = array)[0] = array2[0] + "--s";
				uriBuilder.Host = string.Join(".", array);
				serviceUrls.AlternateEndpoint = uriBuilder.Uri;
			}
			return serviceUrls;
		}
		public AuthenticationCredentials Authenticate(AuthenticationCredentials authenticationCredentials)
		{
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials, "authenticationCredentials");
			switch (this.AuthenticationType)
			{
			case AuthenticationProviderType.ActiveDirectory:
				ServiceMetadataUtility.AdjustUserNameForWindows(authenticationCredentials.ClientCredentials);
				return authenticationCredentials;
			case AuthenticationProviderType.Federation:
				return this.AuthenticateFederationInternal(authenticationCredentials);
			case AuthenticationProviderType.LiveId:
				return this.AuthenticateLiveIdInternal(authenticationCredentials);
			case AuthenticationProviderType.OnlineFederation:
				if (this.ShouldAuthenticateWithLiveId(authenticationCredentials.ClientCredentials))
				{
					return this.AuthenticateHybridLiveIdInternal(authenticationCredentials);
				}
				return this.AuthenticateOnlineFederationInternal(authenticationCredentials);
			default:
				return authenticationCredentials;
			}
		}
		private AuthenticationCredentials AuthenticateFederationInternal(AuthenticationCredentials authenticationCredentials)
		{
			if (authenticationCredentials.SecurityTokenResponse != null)
			{
				return this.AuthenticateFederationTokenInternal(authenticationCredentials);
			}
			if (authenticationCredentials.AppliesTo == null)
			{
				authenticationCredentials.AppliesTo = this.CurrentServiceEndpoint.Address.Uri;
			}
			authenticationCredentials.EndpointType = this.GetCredentialsEndpointType(authenticationCredentials.ClientCredentials);
			authenticationCredentials.IssuerEndpoints = ((authenticationCredentials.HomeRealm != null) ? this.CrossRealmIssuerEndpoints[authenticationCredentials.HomeRealm] : this.IssuerEndpoints);
			authenticationCredentials.SecurityTokenResponse = this.AuthenticateInternal(authenticationCredentials);
			return authenticationCredentials;
		}
		private AuthenticationCredentials AuthenticateFederationTokenInternal(AuthenticationCredentials authenticationCredentials)
		{
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			if (authenticationCredentials.AppliesTo == null)
			{
				authenticationCredentials.AppliesTo = this.CurrentServiceEndpoint.Address.Uri;
			}
			authenticationCredentials.EndpointType = this._tokenEndpointType;
			authenticationCredentials.KeyType = string.Empty;
			authenticationCredentials.IssuerEndpoints = this.IssuerEndpoints;
			authenticationCredentials2.SecurityTokenResponse = this.AuthenticateInternal(authenticationCredentials);
			return authenticationCredentials2;
		}
		private AuthenticationCredentials AuthenticateLiveIdInternal(AuthenticationCredentials authenticationCredentials)
		{
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.ClientCredentials, "authenticationCredentials.ClientCredentials");
			ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.ClientCredentials.UserName.UserName, "authenticationCredentials.ClientCredentials.UserName.UserName");
			ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.ClientCredentials.UserName.Password, "authenticationCredentials.ClientCredentials.UserName.Password");
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials, "authenticationCredentials.SupportingCredentials");
			OnlinePolicyConfiguration parameter = this.PolicyConfiguration as OnlinePolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(parameter, "onlinePolicy");
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			if (authenticationCredentials.SupportingCredentials.SecurityTokenResponse == null)
			{
				ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials.ClientCredentials, "authenticationCredentials.SupportingCredentials.ClientCredentials");
				ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.UserName, "authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.UserName");
				ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.Password, "authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.Password");
				authenticationCredentials.SupportingCredentials.SecurityTokenResponse = this.AuthenticateDevice(authenticationCredentials.SupportingCredentials.ClientCredentials);
			}
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials.SecurityTokenResponse, "deviceTokenResponse");
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			authenticationCredentials2.SecurityTokenResponse = this.Authenticate(authenticationCredentials.ClientCredentials, authenticationCredentials.SupportingCredentials.SecurityTokenResponse);
			return authenticationCredentials2;
		}
		private AuthenticationCredentials AuthenticateHybridLiveIdInternal(AuthenticationCredentials authenticationCredentials)
		{
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.ClientCredentials, "authenticationCredentials.ClientCredentials");
			ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.ClientCredentials.UserName.UserName, "authenticationCredentials.ClientCredentials.UserName.UserName");
			ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.ClientCredentials.UserName.Password, "authenticationCredentials.ClientCredentials.UserName.Password");
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials, "authenticationCredentials.SupportingCredentials");
			OnlinePolicyConfiguration parameter = this.PolicyConfiguration as OnlinePolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(parameter, "onlinePolicy");
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			IdentityProviderTrustConfiguration liveTrustConfig = this.GetLiveTrustConfig<LiveIdentityProviderTrustConfiguration>();
			ClientExceptionHelper.ThrowIfNull(liveTrustConfig, "idp");
			System.ServiceModel.EndpointAddress tokenEndpoint = new System.ServiceModel.EndpointAddress(liveTrustConfig.Endpoint, new System.ServiceModel.Channels.AddressHeader[0]);
			if (authenticationCredentials.SupportingCredentials.SecurityTokenResponse == null)
			{
				ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials.ClientCredentials, "authenticationCredentials.SupportingCredentials.ClientCredentials");
				ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.UserName, "authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.UserName");
				ClientExceptionHelper.ThrowIfNullOrEmpty(authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.Password, "authenticationCredentials.SupportingCredentials.ClientCredentials.UserName.Password");
				authenticationCredentials.SupportingCredentials.SecurityTokenResponse = this.IssueHybridLiveId(authenticationCredentials.SupportingCredentials.ClientCredentials, null, string.Empty, liveTrustConfig, tokenEndpoint);
			}
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SupportingCredentials.SecurityTokenResponse, "deviceTokenResponse");
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			authenticationCredentials2.SecurityTokenResponse = this.IssueHybridLiveId(authenticationCredentials.ClientCredentials, authenticationCredentials.SupportingCredentials.SecurityTokenResponse, string.Empty, liveTrustConfig, tokenEndpoint);
			return authenticationCredentials2;
		}
		private SecurityTokenResponse IssueHybridLiveId(System.ServiceModel.Description.ClientCredentials clientCredentials, SecurityTokenResponse deviceToken, string keyType, IdentityProviderTrustConfiguration idp, System.ServiceModel.EndpointAddress tokenEndpoint)
		{
			ClientExceptionHelper.ThrowIfNull(clientCredentials, "clientCredentials");
			ClientExceptionHelper.ThrowIfNull(idp, "idp");
			ClientExceptionHelper.ThrowIfNull(tokenEndpoint, "tokenEndpoint");
			string uri = (deviceToken == null) ? idp.LiveIdAppliesTo : idp.AppliesTo;
			ClientExceptionHelper.ThrowIfNull(idp.Binding, "idp.Binding");
			LiveIdTrustChannelFactory liveIdTrustChannelFactory = null;
			Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel wSTrustChannel = null;
			SecurityTokenResponse result;
			try
			{
				liveIdTrustChannelFactory = new LiveIdTrustChannelFactory(idp.Binding, tokenEndpoint, idp);
				liveIdTrustChannelFactory.Credentials.UserName.UserName = clientCredentials.UserName.UserName;
				liveIdTrustChannelFactory.Credentials.UserName.Password = clientCredentials.UserName.Password;
				if (deviceToken != null)
				{
					liveIdTrustChannelFactory.DeviceTokenResponse = deviceToken;
				}
				lock (ServiceConfiguration<TService>._lockObject)
				{
					liveIdTrustChannelFactory.ConfigureChannelFactory<Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustChannelContract>();
				}
				wSTrustChannel = (Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel)liveIdTrustChannelFactory.CreateChannel();
				RequestSecurityToken requestSecurityToken = new RequestSecurityToken(idp.IssueRequestType)
				{
					AppliesTo = new System.ServiceModel.EndpointAddress(uri)
				};
				if (!string.IsNullOrEmpty(keyType))
				{
					requestSecurityToken.KeyType = keyType;
				}
				RequestSecurityTokenResponse response = null;
				System.IdentityModel.Tokens.SecurityToken token = wSTrustChannel.Issue(requestSecurityToken, out response);
				result = new SecurityTokenResponse
				{
					Token = token,
					Response = response
				};
			}
			finally
			{
				if (liveIdTrustChannelFactory != null)
				{
					liveIdTrustChannelFactory.Close(true);
				}
				liveIdTrustChannelFactory = null;
				if (wSTrustChannel != null)
				{
					wSTrustChannel.Close(true);
				}
				wSTrustChannel = null;
			}
			return result;
		}
		private AuthenticationCredentials AuthenticateOnlineFederationInternal(AuthenticationCredentials authenticationCredentials)
		{
			OnlinePolicyConfiguration onlinePolicyConfiguration = this.PolicyConfiguration as OnlinePolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(onlinePolicyConfiguration, "onlinePolicy");
			OrgIdentityProviderTrustConfiguration orgIdentityProviderTrustConfiguration = onlinePolicyConfiguration.OnlineProviders.Values.OfType<OrgIdentityProviderTrustConfiguration>().FirstOrDefault<OrgIdentityProviderTrustConfiguration>();
			ClientExceptionHelper.ThrowIfNull(orgIdentityProviderTrustConfiguration, "liveTrustConfig");
			if (authenticationCredentials.SecurityTokenResponse != null)
			{
				return this.AuthenticateOnlineFederationTokenInternal(orgIdentityProviderTrustConfiguration, authenticationCredentials);
			}
			bool flag = true;
			if (authenticationCredentials.HomeRealm == null)
			{
				IdentityProvider identityProvider = (!string.IsNullOrEmpty(authenticationCredentials.UserPrincipalName)) ? this.GetIdentityProvider(authenticationCredentials.UserPrincipalName) : this.GetIdentityProvider(authenticationCredentials.ClientCredentials);
				ClientExceptionHelper.ThrowIfNull(identityProvider, "identityProvider");
				authenticationCredentials.HomeRealm = identityProvider.ServiceUrl;
				flag = (identityProvider.IdentityProviderType == IdentityProviderType.OrgId);
				if (flag)
				{
					ClientExceptionHelper.Assert(onlinePolicyConfiguration.OnlineProviders.ContainsKey(authenticationCredentials.HomeRealm), "Online Identity Provider NOT found!  {0}", new object[]
					{
						identityProvider.ServiceUrl
					});
				}
			}
			if (flag)
			{
				this.AuthenticateWithOrgIdForACS(authenticationCredentials, new System.Uri(onlinePolicyConfiguration.SecureTokenServiceIdentifier, System.UriKind.RelativeOrAbsolute));
				return this.AuthenticateTokenWithACSForCrm(authenticationCredentials, this.CurrentServiceEndpoint.Address.Uri.GetServiceRoot(), null);
			}
			this.AuthenticateWithADFSForOrgId(authenticationCredentials, orgIdentityProviderTrustConfiguration.Identifier);
			AuthenticationCredentials authenticationCredentials2 = this.AuthenticateFederatedTokenWithOrgIdForACS(authenticationCredentials, new System.Uri(onlinePolicyConfiguration.SecureTokenServiceIdentifier, System.UriKind.RelativeOrAbsolute), orgIdentityProviderTrustConfiguration.Endpoint.GetServiceRoot());
			return this.AuthenticateTokenWithACSForCrm(authenticationCredentials2, this.CurrentServiceEndpoint.Address.Uri.GetServiceRoot(), null);
		}
		private AuthenticationCredentials AuthenticateFederatedTokenWithOrgIdForACS(AuthenticationCredentials authenticationCredentials, System.Uri identifier, System.Uri homeRealmUri)
		{
			ClientExceptionHelper.ThrowIfNull(identifier, "identifier");
			ClientExceptionHelper.ThrowIfNull(homeRealmUri, "homeRealmUri");
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SecurityTokenResponse, "authenticationCredentials.SecurityTokenResponse");
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			authenticationCredentials2.AppliesTo = identifier;
			authenticationCredentials2.IssuerEndpoints = this.CrossRealmIssuerEndpoints[homeRealmUri];
			authenticationCredentials2.EndpointType = TokenServiceCredentialType.SymmetricToken;
			authenticationCredentials2.SecurityTokenResponse = this.AuthenticateInternal(authenticationCredentials2);
			return authenticationCredentials2;
		}
		private void AuthenticateWithADFSForOrgId(AuthenticationCredentials authenticationCredentials, System.Uri identifier)
		{
			authenticationCredentials.AppliesTo = identifier;
			authenticationCredentials.KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer";
			authenticationCredentials.EndpointType = this.GetCredentialsEndpointType(authenticationCredentials.ClientCredentials);
			authenticationCredentials.IssuerEndpoints = this.CrossRealmIssuerEndpoints[authenticationCredentials.HomeRealm];
			authenticationCredentials.SecurityTokenResponse = this.AuthenticateInternal(authenticationCredentials);
		}
		private void AuthenticateWithOrgIdForACS(AuthenticationCredentials authenticationCredentials, System.Uri identifier)
		{
			authenticationCredentials.AppliesTo = identifier;
			authenticationCredentials.EndpointType = this.GetCredentialsEndpointType(authenticationCredentials.ClientCredentials);
			authenticationCredentials.IssuerEndpoints = this.CrossRealmIssuerEndpoints[authenticationCredentials.HomeRealm];
			authenticationCredentials.EndpointType = TokenServiceCredentialType.Username;
			authenticationCredentials.SecurityTokenResponse = this.AuthenticateInternal(authenticationCredentials);
		}
		private AuthenticationCredentials AuthenticateTokenWithACSForCrm(AuthenticationCredentials authenticationCredentials, System.Uri appliesTo, System.Uri acsEndpoint = null)
		{
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.SecurityTokenResponse, "authenticationCredentials.SecurityTokenResponse");
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			authenticationCredentials2.AppliesTo = appliesTo;
			if (acsEndpoint != null)
			{
				authenticationCredentials2.IssuerEndpoints = this.CrossRealmIssuerEndpoints[acsEndpoint];
			}
			else
			{
				authenticationCredentials2.IssuerEndpoints = this.IssuerEndpoints;
			}
			authenticationCredentials2.KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer";
			authenticationCredentials2.EndpointType = TokenServiceCredentialType.AsymmetricToken;
			authenticationCredentials2.SecurityTokenResponse = this.Issue(authenticationCredentials2);
			return authenticationCredentials2;
		}
		private AuthenticationCredentials AuthenticateOnlineFederationTokenInternal(IdentityProviderTrustConfiguration liveTrustConfig, AuthenticationCredentials authenticationCredentials)
		{
			AuthenticationCredentials authenticationCredentials2 = new AuthenticationCredentials();
			authenticationCredentials2.SupportingCredentials = authenticationCredentials;
			string appliesTo = (authenticationCredentials.AppliesTo != null) ? authenticationCredentials.AppliesTo.AbsoluteUri : liveTrustConfig.AppliesTo;
			System.Uri crossRealmSts = authenticationCredentials.HomeRealm ?? liveTrustConfig.Endpoint.GetServiceRoot();
			authenticationCredentials2.SecurityTokenResponse = this.AuthenticateCrossRealm(authenticationCredentials.SecurityTokenResponse.Token, appliesTo, crossRealmSts);
			return authenticationCredentials2;
		}
		internal IdentityProvider GetIdentityProvider(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			string text = string.Empty;
			if (!StringExtensions.IsNullOrWhiteSpace(clientCredentials.UserName.UserName))
			{
				text = this.ExtractUserName(clientCredentials.UserName.UserName);
			}
			else if (!StringExtensions.IsNullOrWhiteSpace(clientCredentials.Windows.ClientCredential.UserName))
			{
				text = this.ExtractUserName(clientCredentials.Windows.ClientCredential.UserName);
			}
			ClientExceptionHelper.Assert(!string.IsNullOrEmpty(text), "clientCredentials.UserName.UserName or clientCredentials.Windows.ClientCredential.UserName MUST be populated!");
			return this.GetIdentityProvider(text);
		}
		private string ExtractUserName(string userName)
		{
			if (!userName.Contains('@'))
			{
				return string.Empty;
			}
			return userName;
		}
		private ServiceConfiguration()
		{
		}
		public ServiceConfiguration(System.Uri serviceUri) : this(serviceUri, true)
		{
		}
		internal ServiceConfiguration(System.Uri serviceUri, bool checkForSecondary)
		{
			this.ServiceUri = serviceUri;
			this.ServiceEndpointMetadata = ServiceMetadataUtility.RetrieveServiceEndpointMetadata(typeof(TService), this.ServiceUri, checkForSecondary);
			ClientExceptionHelper.ThrowIfNull(this.ServiceEndpointMetadata, "ServiceEndpointMetadata");
			if (this.ServiceEndpointMetadata.ServiceEndpoints.Count == 0)
			{
				StringBuilder stringBuilder = new StringBuilder();
				if (this.ServiceEndpointMetadata.MetadataConversionErrors.Count > 0)
				{
					foreach (System.ServiceModel.Description.MetadataConversionError current in this.ServiceEndpointMetadata.MetadataConversionErrors)
					{
						stringBuilder.Append(current.Message);
					}
				}
				throw new InvalidOperationException(ClientExceptionHelper.FormatMessage(0, new object[]
				{
					"The provided uri did not return any Service Endpoints!\n{0}",
					stringBuilder.ToString()
				}));
			}
			this.ServiceEndpoints = this.ServiceEndpointMetadata.ServiceEndpoints;
			if (this.CurrentServiceEndpoint != null)
			{
				this.CrossRealmIssuerEndpoints = new CrossRealmIssuerEndpointCollection();
				this.SetAuthenticationConfiguration();
				if (checkForSecondary)
				{
					this.SetEndpointSwitchingBehavior();
					return;
				}
				if (this.CurrentServiceEndpoint.Address.Uri != serviceUri)
				{
					ServiceMetadataUtility.ReplaceEndpointAddress(this.CurrentServiceEndpoint, serviceUri);
				}
				this.PrimaryEndpoint = serviceUri;
			}
		}
		private void AddLiveIssuerEndpointsToCrossRealmIssuers(IdentityProviderTrustConfiguration identityProviderTrustConfiguration)
		{
			IssuerEndpointDictionary issuerEndpointDictionary = ServiceMetadataUtility.RetrieveLiveIdIssuerEndpoints(identityProviderTrustConfiguration);
			if (issuerEndpointDictionary != null)
			{
				this.CrossRealmIssuerEndpoints[identityProviderTrustConfiguration.Endpoint.GetServiceRoot()] = issuerEndpointDictionary;
			}
		}
		private void SetAuthenticationConfiguration()
		{
			if (this.CurrentServiceEndpoint.Binding == null)
			{
				return;
			}
			System.ServiceModel.Channels.BindingElementCollection bindingElementCollection = this.CurrentServiceEndpoint.Binding.CreateBindingElements();
			AuthenticationPolicy authenticationPolicy = bindingElementCollection.Find<AuthenticationPolicy>();
			if (authenticationPolicy != null && authenticationPolicy.PolicyElements.ContainsKey("AuthenticationType"))
			{
				string value = authenticationPolicy.PolicyElements["AuthenticationType"];
				AuthenticationProviderType authenticationProviderType;
				if (!string.IsNullOrEmpty(value) && EnumExtensions.TryParse<AuthenticationProviderType>(value, out authenticationProviderType))
				{
					switch (authenticationProviderType)
					{
					case AuthenticationProviderType.Federation:
						break;
					case AuthenticationProviderType.LiveId:
						this.IssuerEndpoints = ServiceMetadataUtility.RetrieveIssuerEndpoints(AuthenticationProviderType.LiveId, this.ServiceEndpoints, false);
						authenticationPolicy.PolicyElements["LiveEndpoint"] = this.IssuerEndpoints[TokenServiceCredentialType.Username.ToString()].IssuerAddress.Uri.AbsoluteUri;
						this.PolicyConfiguration = new LiveIdPolicyConfiguration(authenticationPolicy);
						return;
					case AuthenticationProviderType.OnlineFederation:
					{
						string text = authenticationPolicy.PolicyElements["SecureTokenServiceIdentifier"];
						if (!string.IsNullOrEmpty(text))
						{
							this.IssuerEndpoints = ServiceMetadataUtility.RetrieveACSIssuerEndpoints(new System.Uri(text));
						}
						else
						{
							this.IssuerEndpoints = ServiceMetadataUtility.RetrieveIssuerEndpoints(AuthenticationProviderType.OnlineFederation, this.ServiceEndpoints, true);
						}
						this.PolicyConfiguration = new OnlineFederationPolicyConfiguration(authenticationPolicy);
						using (Dictionary<System.Uri, IdentityProviderTrustConfiguration>.ValueCollection.Enumerator enumerator = ((OnlineFederationPolicyConfiguration)this.PolicyConfiguration).OnlineProviders.Values.GetEnumerator())
						{
							while (enumerator.MoveNext())
							{
								IdentityProviderTrustConfiguration current = enumerator.Current;
								this.AddLiveIssuerEndpointsToCrossRealmIssuers(current);
							}
							return;
						}
					}
					default:
						this.PolicyConfiguration = new WindowsPolicyConfiguration(authenticationPolicy);
						return;
					}
					this.IssuerEndpoints = ServiceMetadataUtility.RetrieveIssuerEndpoints(AuthenticationProviderType.Federation, this.ServiceEndpoints, true);
					this.PolicyConfiguration = new ClaimsPolicyConfiguration(authenticationPolicy);
					return;
				}
			}
		}
		public System.ServiceModel.ChannelFactory<TService> CreateChannelFactory(ClientAuthenticationType clientAuthenticationType)
		{
			ClientExceptionHelper.ThrowIfNull(this.CurrentServiceEndpoint, "CurrentServiceEndpoint");
			if (this.ClaimsEnabledService)
			{
				IssuerEndpoint issuerEndpoint = this.IssuerEndpoints.GetIssuerEndpoint((clientAuthenticationType == ClientAuthenticationType.SecurityToken) ? this._tokenEndpointType : TokenServiceCredentialType.Kerberos);
				if (issuerEndpoint != null)
				{
					lock (ServiceConfiguration<TService>._lockObject)
					{
						this.CurrentServiceEndpoint.Binding = ServiceMetadataUtility.SetIssuer(this.CurrentServiceEndpoint.Binding, issuerEndpoint);
					}
				}
			}
			System.ServiceModel.ChannelFactory<TService> channelFactory = this.CreateLocalChannelFactory();
			channelFactory.Credentials.SupportInteractive = false;
			return channelFactory;
		}
		public System.ServiceModel.ChannelFactory<TService> CreateChannelFactory(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			ClientExceptionHelper.ThrowIfNull(this.CurrentServiceEndpoint, "CurrentServiceEndpoint");
			if (this.ClaimsEnabledService)
			{
				TokenServiceCredentialType credentialsEndpointType = this.GetCredentialsEndpointType(clientCredentials);
				IssuerEndpoint issuerEndpoint = this.IssuerEndpoints.GetIssuerEndpoint(credentialsEndpointType);
				if (issuerEndpoint != null)
				{
					lock (ServiceConfiguration<TService>._lockObject)
					{
						this.CurrentServiceEndpoint.Binding = ServiceMetadataUtility.SetIssuer(this.CurrentServiceEndpoint.Binding, issuerEndpoint);
					}
				}
			}
			System.ServiceModel.ChannelFactory<TService> channelFactory = this.CreateLocalChannelFactory();
			this.ConfigureCredentials(channelFactory, clientCredentials);
			channelFactory.Credentials.SupportInteractive = (clientCredentials != null && clientCredentials.SupportInteractive);
			return channelFactory;
		}
		public SecurityTokenResponse AuthenticateCrossRealm(System.ServiceModel.Description.ClientCredentials clientCredentials, string appliesTo, System.Uri crossRealmSts)
		{
			if (crossRealmSts != null)
			{
				AuthenticationCredentials authenticationCredentials = new AuthenticationCredentials();
				authenticationCredentials.AppliesTo = ((!StringExtensions.IsNullOrWhiteSpace(appliesTo)) ? new System.Uri(appliesTo) : null);
				authenticationCredentials.KeyType = string.Empty;
				authenticationCredentials.ClientCredentials = clientCredentials;
				authenticationCredentials.SecurityTokenResponse = null;
				IdentityProviderTrustConfiguration identityProviderTrustConfiguration = this.TryGetOnlineTrustConfiguration(crossRealmSts);
				authenticationCredentials.EndpointType = ((identityProviderTrustConfiguration != null) ? TokenServiceCredentialType.Username : this.GetCredentialsEndpointType(clientCredentials));
				authenticationCredentials.IssuerEndpoints = this.CrossRealmIssuerEndpoints[crossRealmSts];
				if (this.AuthenticationType == AuthenticationProviderType.OnlineFederation && identityProviderTrustConfiguration == null)
				{
					authenticationCredentials.KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer";
				}
				return this.AuthenticateInternal(authenticationCredentials);
			}
			return null;
		}
		public SecurityTokenResponse AuthenticateCrossRealm(System.IdentityModel.Tokens.SecurityToken securityToken, string appliesTo, System.Uri crossRealmSts)
		{
			if (crossRealmSts != null)
			{
				AuthenticationCredentials authenticationCredentials = new AuthenticationCredentials();
				authenticationCredentials.AppliesTo = ((!StringExtensions.IsNullOrWhiteSpace(appliesTo)) ? new System.Uri(appliesTo) : null);
				authenticationCredentials.KeyType = string.Empty;
				authenticationCredentials.ClientCredentials = null;
				authenticationCredentials.SecurityTokenResponse = new SecurityTokenResponse
				{
					Token = securityToken
				};
				bool flag = true;
				if (this.AuthenticationType == AuthenticationProviderType.OnlineFederation)
				{
					IdentityProviderTrustConfiguration identityProviderTrustConfiguration = this.TryGetOnlineTrustConfiguration(crossRealmSts);
					if (identityProviderTrustConfiguration != null && identityProviderTrustConfiguration.Endpoint.GetServiceRoot() == crossRealmSts)
					{
						authenticationCredentials.EndpointType = TokenServiceCredentialType.SymmetricToken;
						flag = false;
					}
				}
				if (flag)
				{
					authenticationCredentials.EndpointType = this._tokenEndpointType;
				}
				authenticationCredentials.IssuerEndpoints = this.CrossRealmIssuerEndpoints[crossRealmSts];
				return this.AuthenticateInternal(authenticationCredentials);
			}
			return null;
		}
		private IdentityProviderTrustConfiguration TryGetOnlineTrustConfiguration()
		{
			OnlinePolicyConfiguration onlinePolicyConfiguration = this.PolicyConfiguration as OnlinePolicyConfiguration;
			if (onlinePolicyConfiguration == null)
			{
				return null;
			}
			return onlinePolicyConfiguration.OnlineProviders.Values.OfType<OrgIdentityProviderTrustConfiguration>().FirstOrDefault<OrgIdentityProviderTrustConfiguration>();
		}
		private IdentityProviderTrustConfiguration GetLiveTrustConfig<T>() where T : IdentityProviderTrustConfiguration
		{
			OnlinePolicyConfiguration onlinePolicyConfiguration = this.PolicyConfiguration as OnlinePolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(onlinePolicyConfiguration, "liveConfiguration");
			IdentityProviderTrustConfiguration identityProviderTrustConfiguration = onlinePolicyConfiguration.OnlineProviders.Values.OfType<T>().FirstOrDefault<T>();
			ClientExceptionHelper.ThrowIfNull(identityProviderTrustConfiguration, "liveTrustConfig");
			return identityProviderTrustConfiguration;
		}
		private IdentityProviderTrustConfiguration GetOnlineTrustConfiguration(System.Uri crossRealmSts)
		{
			OnlineFederationPolicyConfiguration onlineFederationPolicyConfiguration = this.PolicyConfiguration as OnlineFederationPolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(onlineFederationPolicyConfiguration, "liveFederationConfiguration");
			if (onlineFederationPolicyConfiguration.OnlineProviders.ContainsKey(crossRealmSts))
			{
				return onlineFederationPolicyConfiguration.OnlineProviders[crossRealmSts];
			}
			return null;
		}
		private IdentityProviderTrustConfiguration TryGetOnlineTrustConfiguration(System.Uri crossRealmSts)
		{
			OnlineFederationPolicyConfiguration onlineFederationPolicyConfiguration = this.PolicyConfiguration as OnlineFederationPolicyConfiguration;
			if (onlineFederationPolicyConfiguration != null && onlineFederationPolicyConfiguration.OnlineProviders.ContainsKey(crossRealmSts))
			{
				return onlineFederationPolicyConfiguration.OnlineProviders[crossRealmSts];
			}
			return null;
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			if (this.CurrentServiceEndpoint != null)
			{
				AuthenticationCredentials authenticationCredentials = this.Authenticate(new AuthenticationCredentials
				{
					ClientCredentials = clientCredentials
				});
				if (authenticationCredentials != null && authenticationCredentials.SecurityTokenResponse != null)
				{
					return authenticationCredentials.SecurityTokenResponse;
				}
			}
			return null;
		}
		internal SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials, System.Uri uri, string keyType)
		{
			return this.AuthenticateInternal(new AuthenticationCredentials
			{
				AppliesTo = uri,
				EndpointType = this.GetCredentialsEndpointType(clientCredentials),
				KeyType = keyType,
				IssuerEndpoints = this.IssuerEndpoints,
				ClientCredentials = clientCredentials,
				SecurityTokenResponse = null
			});
		}
		public SecurityTokenResponse Authenticate(System.IdentityModel.Tokens.SecurityToken securityToken)
		{
			ClientExceptionHelper.ThrowIfNull(securityToken, "securityToken");
			if (this.AuthenticationType == AuthenticationProviderType.OnlineFederation)
			{
				IdentityProviderTrustConfiguration identityProviderTrustConfiguration = this.TryGetOnlineTrustConfiguration();
				if (identityProviderTrustConfiguration == null)
				{
					return null;
				}
				return this.AuthenticateCrossRealm(securityToken, identityProviderTrustConfiguration.AppliesTo, identityProviderTrustConfiguration.Endpoint.GetServiceRoot());
			}
			else
			{
				if (this.CurrentServiceEndpoint != null)
				{
					return this.AuthenticateInternal(new AuthenticationCredentials
					{
						AppliesTo = this.CurrentServiceEndpoint.Address.Uri,
						EndpointType = this._tokenEndpointType,
						KeyType = string.Empty,
						IssuerEndpoints = this.IssuerEndpoints,
						ClientCredentials = null,
						SecurityTokenResponse = new SecurityTokenResponse
						{
							Token = securityToken
						}
					});
				}
				return null;
			}
		}
		internal SecurityTokenResponse Authenticate(System.IdentityModel.Tokens.SecurityToken securityToken, System.Uri uri, string keyType)
		{
			ClientExceptionHelper.ThrowIfNull(securityToken, "securityToken");
			if (uri != null)
			{
				return this.AuthenticateInternal(new AuthenticationCredentials
				{
					AppliesTo = uri.GetServiceRoot(),
					EndpointType = this._tokenEndpointType,
					KeyType = keyType,
					IssuerEndpoints = this.IssuerEndpoints,
					ClientCredentials = null,
					SecurityTokenResponse = new SecurityTokenResponse
					{
						Token = securityToken
					}
				});
			}
			return null;
		}
		public SecurityTokenResponse AuthenticateDevice(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			if (this.AuthenticationType == AuthenticationProviderType.LiveId)
			{
				return this.AuthenticateLiveIdInternal(clientCredentials, null, string.Empty);
			}
			return null;
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials, SecurityTokenResponse deviceTokenResponse)
		{
			return this.Authenticate(clientCredentials, deviceTokenResponse, string.Empty);
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials, SecurityTokenResponse deviceTokenResponse, string keyType)
		{
			if (deviceTokenResponse == null && this.CurrentServiceEndpoint != null)
			{
				AuthenticationCredentials authenticationCredentials = this.Authenticate(new AuthenticationCredentials
				{
					ClientCredentials = clientCredentials
				});
				if (authenticationCredentials != null && authenticationCredentials.SecurityTokenResponse != null)
				{
					return authenticationCredentials.SecurityTokenResponse;
				}
			}
			if (this.AuthenticationType == AuthenticationProviderType.LiveId)
			{
				return this.AuthenticateLiveIdInternal(clientCredentials, deviceTokenResponse, keyType);
			}
			return null;
		}
		private SecurityTokenResponse AuthenticateLiveIdInternal(System.ServiceModel.Description.ClientCredentials clientCredentials, SecurityTokenResponse deviceToken, string keyType)
		{
			ClientExceptionHelper.Assert(this.AuthenticationType == AuthenticationProviderType.LiveId, "Authenticate is not supported when not in claims mode with LiveId!");
			ClientExceptionHelper.ThrowIfNull(clientCredentials, "clientCredentials");
			OnlinePolicyConfiguration parameter = this.PolicyConfiguration as OnlinePolicyConfiguration;
			ClientExceptionHelper.ThrowIfNull(parameter, "liveConfiguration");
			IdentityProviderTrustConfiguration liveTrustConfig = this.GetLiveTrustConfig<LiveIdentityProviderTrustConfiguration>();
			IssuerEndpoint issuerEndpoint = this.IssuerEndpoints.GetIssuerEndpoint(TokenServiceCredentialType.Username);
			string uri = (deviceToken == null) ? liveTrustConfig.LiveIdAppliesTo : liveTrustConfig.AppliesTo;
			if (issuerEndpoint != null)
			{
				string requestType = string.Empty;
				System.ServiceModel.Channels.Binding binding = liveTrustConfig.Binding;
				requestType = liveTrustConfig.IssueRequestType;
				ClientExceptionHelper.ThrowIfNull(binding, "issuerBinding");
				LiveIdTrustChannelFactory liveIdTrustChannelFactory = null;
				Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel wSTrustChannel = null;
				try
				{
					liveIdTrustChannelFactory = new LiveIdTrustChannelFactory(binding, issuerEndpoint.IssuerAddress, liveTrustConfig);
					liveIdTrustChannelFactory.Credentials.UserName.UserName = clientCredentials.UserName.UserName;
					liveIdTrustChannelFactory.Credentials.UserName.Password = clientCredentials.UserName.Password;
					if (deviceToken != null)
					{
						liveIdTrustChannelFactory.DeviceTokenResponse = deviceToken;
					}
					lock (ServiceConfiguration<TService>._lockObject)
					{
						liveIdTrustChannelFactory.ConfigureChannelFactory<Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustChannelContract>();
					}
					wSTrustChannel = (Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel)liveIdTrustChannelFactory.CreateChannel();
					RequestSecurityToken requestSecurityToken = new RequestSecurityToken(requestType)
					{
						AppliesTo = new System.ServiceModel.EndpointAddress(uri)
					};
					if (!string.IsNullOrEmpty(keyType))
					{
						requestSecurityToken.KeyType = keyType;
					}
					RequestSecurityTokenResponse response = null;
					System.IdentityModel.Tokens.SecurityToken token = wSTrustChannel.Issue(requestSecurityToken, out response);
					return new SecurityTokenResponse
					{
						Token = token,
						Response = response
					};
				}
				finally
				{
					if (liveIdTrustChannelFactory != null)
					{
						liveIdTrustChannelFactory.Close(true);
					}
					liveIdTrustChannelFactory = null;
					if (wSTrustChannel != null)
					{
						wSTrustChannel.Close(true);
					}
					wSTrustChannel = null;
				}
			}
			return null;
		}
		public IdentityProvider GetIdentityProvider(string userPrincipalName)
		{
			IdentityProviderTrustConfiguration identityProviderTrustConfiguration = this.TryGetOnlineTrustConfiguration();
			if (identityProviderTrustConfiguration == null)
			{
				return null;
			}
			return IdentityProviderLookup.Instance.GetIdentityProvider(identityProviderTrustConfiguration.Endpoint.GetServiceRoot(), identityProviderTrustConfiguration.Endpoint.GetServiceRoot(), userPrincipalName);
		}
		private SecurityTokenResponse AuthenticateInternal(AuthenticationCredentials authenticationCredentials)
		{
			ClientExceptionHelper.Assert(this.AuthenticationType == AuthenticationProviderType.Federation || this.AuthenticationType == AuthenticationProviderType.OnlineFederation, "Authenticate is not supported when not in claims mode!");
			if (this.ClaimsEnabledService)
			{
				if (authenticationCredentials.IssuerEndpoint.CredentialType != TokenServiceCredentialType.Kerberos)
				{
					return this.Issue(authenticationCredentials);
				}
				bool flag = false;
				int num = 0;
				do
				{
					try
					{
						return this.Issue(authenticationCredentials);
					}
					catch (System.IdentityModel.Tokens.SecurityTokenValidationException)
					{
						flag = false;
						if (authenticationCredentials.IssuerEndpoints.ContainsKey(TokenServiceCredentialType.Windows.ToString()))
						{
							authenticationCredentials.EndpointType = TokenServiceCredentialType.Windows;
							flag = (++num < 2);
						}
					}
					catch (System.ServiceModel.Security.SecurityNegotiationException)
					{
						flag = (++num < 2);
					}
					catch (System.ServiceModel.FaultException)
					{
						if (authenticationCredentials.IssuerEndpoints.ContainsKey(TokenServiceCredentialType.Windows.ToString()))
						{
							authenticationCredentials.EndpointType = TokenServiceCredentialType.Windows;
							flag = (++num < 2);
						}
					}
				}
				while (flag);
			}
			return null;
		}
		private SecurityTokenResponse Issue(AuthenticationCredentials authenticationCredentials)
		{
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials, "authenticationCredentials");
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.IssuerEndpoint, "authenticationCredentials.IssuerEndpoint");
			ClientExceptionHelper.ThrowIfNull(authenticationCredentials.AppliesTo, "authenticationCredentials.AppliesTo");
			Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory wSTrustChannelFactory = null;
			Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel wSTrustChannel = null;
			try
			{
				authenticationCredentials.RequestType = ((authenticationCredentials.IssuerEndpoint.TrustVersion == System.ServiceModel.Security.TrustVersion.WSTrust13) ? "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue" : "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue");
				wSTrustChannelFactory = new Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory(authenticationCredentials.IssuerEndpoint.IssuerBinding, authenticationCredentials.IssuerEndpoint.IssuerAddress);
				System.IdentityModel.Tokens.SecurityToken securityToken = (authenticationCredentials.SecurityTokenResponse != null && authenticationCredentials.SecurityTokenResponse.Token != null) ? authenticationCredentials.SecurityTokenResponse.Token : ((authenticationCredentials.SupportingCredentials != null && authenticationCredentials.SupportingCredentials.SecurityTokenResponse != null && authenticationCredentials.SupportingCredentials.SecurityTokenResponse.Token != null) ? authenticationCredentials.SupportingCredentials.SecurityTokenResponse.Token : null);
				if (securityToken != null)
				{
					wSTrustChannelFactory.Credentials.SupportInteractive = false;
				}
				else
				{
					this.ConfigureCredentials(wSTrustChannelFactory, authenticationCredentials.ClientCredentials);
				}
				lock (ServiceConfiguration<TService>._lockObject)
				{
					wSTrustChannelFactory.ConfigureChannelFactory<Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustChannelContract>();
				}
				wSTrustChannel = ((securityToken != null) ? ((Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel)wSTrustChannelFactory.CreateChannelWithIssuedToken(securityToken)) : ((Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel)wSTrustChannelFactory.CreateChannel()));
				if (wSTrustChannel != null)
				{
					RequestSecurityToken requestSecurityToken = new RequestSecurityToken(authenticationCredentials.RequestType)
					{
						AppliesTo = new System.ServiceModel.EndpointAddress(authenticationCredentials.AppliesTo, new System.ServiceModel.Channels.AddressHeader[0])
					};
					if (!string.IsNullOrEmpty(authenticationCredentials.KeyType))
					{
						requestSecurityToken.KeyType = authenticationCredentials.KeyType;
					}
					RequestSecurityTokenResponse response;
					System.IdentityModel.Tokens.SecurityToken token = wSTrustChannel.Issue(requestSecurityToken, out response);
					return new SecurityTokenResponse
					{
						Token = token,
						Response = response
					};
				}
			}
			finally
			{
				if (wSTrustChannel != null)
				{
					wSTrustChannel.Close(true);
				}
				wSTrustChannel = null;
				if (wSTrustChannelFactory != null)
				{
					wSTrustChannelFactory.Close(true);
				}
				wSTrustChannelFactory = null;
			}
			return null;
		}
		private void ConfigureCredentials(System.ServiceModel.ChannelFactory channelFactory, System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			if (clientCredentials != null)
			{
				if (clientCredentials.ClientCertificate != null && clientCredentials.ClientCertificate.Certificate != null)
				{
					channelFactory.Credentials.ClientCertificate.Certificate = clientCredentials.ClientCertificate.Certificate;
					return;
				}
				if (clientCredentials.UserName != null && !string.IsNullOrEmpty(clientCredentials.UserName.UserName))
				{
					channelFactory.Credentials.UserName.UserName = clientCredentials.UserName.UserName;
					channelFactory.Credentials.UserName.Password = clientCredentials.UserName.Password;
					return;
				}
				if (clientCredentials.Windows != null && clientCredentials.Windows.ClientCredential != null)
				{
					channelFactory.Credentials.Windows.ClientCredential = clientCredentials.Windows.ClientCredential;
					channelFactory.Credentials.Windows.AllowedImpersonationLevel = clientCredentials.Windows.AllowedImpersonationLevel;
				}
			}
		}
		private TokenServiceCredentialType GetCredentialsEndpointType(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			if (clientCredentials != null)
			{
				if (clientCredentials.UserName != null && !string.IsNullOrEmpty(clientCredentials.UserName.UserName))
				{
					return TokenServiceCredentialType.Username;
				}
				if (clientCredentials.ClientCertificate != null && clientCredentials.ClientCertificate.Certificate != null)
				{
					return TokenServiceCredentialType.Certificate;
				}
				if (clientCredentials.Windows != null && clientCredentials.Windows.ClientCredential != null)
				{
					return TokenServiceCredentialType.Kerberos;
				}
			}
			return TokenServiceCredentialType.Kerberos;
		}
		private System.ServiceModel.ChannelFactory<TService> CreateLocalChannelFactory()
		{
			System.ServiceModel.ChannelFactory<TService> result;
			lock (ServiceConfiguration<TService>._lockObject)
			{
				System.ServiceModel.Description.ServiceEndpoint serviceEndpoint = new System.ServiceModel.Description.ServiceEndpoint(this.CurrentServiceEndpoint.Contract, this.CurrentServiceEndpoint.Binding, this.CurrentServiceEndpoint.Address);
				foreach (System.ServiceModel.Description.IEndpointBehavior current in this.CurrentServiceEndpoint.Behaviors)
				{
					serviceEndpoint.Behaviors.Add(current);
				}
				//serviceEndpoint.IsSystemEndpoint = this.CurrentServiceEndpoint.IsSystemEndpoint;
				serviceEndpoint.ListenUri = this.CurrentServiceEndpoint.ListenUri;
				serviceEndpoint.ListenUriMode = this.CurrentServiceEndpoint.ListenUriMode;
				serviceEndpoint.Name = this.CurrentServiceEndpoint.Name;
				System.ServiceModel.ChannelFactory<TService> channelFactory = new System.ServiceModel.ChannelFactory<TService>(serviceEndpoint);
				if (this.ClaimsEnabledService || this.AuthenticationType == AuthenticationProviderType.LiveId)
				{
					channelFactory.ConfigureChannelFactory<TService>();
				}
				channelFactory.Credentials.IssuedToken.CacheIssuedTokens = true;
				result = channelFactory;
			}
			return result;
		}
	}
}
